﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Haidou.Wpf.Domian.ViewModels
{
	/// <summary>
	/// Implementation of <see cref="INotifyPropertyChanged" /> to simplify models.
	/// From here: 
	/// </summary>
	public abstract class BindableBase : INotifyPropertyChanged
	{
		/// <summary>
		/// Multicast event for property change notifications.   属性更改通知的多播事件。
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// Checks if a property already matches a desired value.  Sets the property and 检查属性是否已经与所需的值匹配。
		/// notifies listeners only when necessary.设置属性和
		///仅在必要时通知侦听器。
		/// </summary>
		/// <typeparam name="T">Type of the property.</typeparam>
		/// <param name="storage">Reference to a property with both getter and setter.</param>
		/// <param name="value">Desired value for the property.</param>
		/// <param name="propertyName">
		/// Name of the property used to notify listeners.  This
		/// value is optional and can be provided automatically when invoked from compilers that
		/// support CallerMemberName.
		/// </param>
		/// <returns>
		/// True if the value was changed, false if the existing value matched the
		/// desired value.
		/// </returns>
		protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string? propertyName = null)
		{
			if (Equals(storage, value))
				return false;

			storage = value;
			OnPropertyChanged(propertyName);
			return true;
		}

		/// <summary>
		/// Notifies listeners that a property value has changed.通知侦听器属性值已更改。
		/// </summary>
		/// <param name="propertyName">
		/// Name of the property used to notify listeners.  This用于通知侦听器的属性的名称。这
		/// value is optional and can be provided automatically when invoked from compilers  值是可选的，可以在从编译器调用时自动提供
		/// that support <see cref="CallerMemberNameAttribute" />.
		/// </param>
		protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
		{
			PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
		}
	}
}
